// -----------------------------
// Author: 		Dhaenens Gert	
// Creation: 	2/21/2015 8:19:30 PM				
// -----------------------------

#include "ThreadHandler.h"

#include "CThread.h"

Bool ThreadHandler::s_IsInitialized = false;
IThreadPoolStatics* ThreadHandler::s_lpThreadPool = nullptr;

class ThreadCallback
{
public:
	ThreadCallback(Flow::CThread* lpThread)
		: m_lpThread(lpThread)
	{
	}

	HRESULT Run(IAsyncAction* lpAction)
	{
		ASSERT(m_lpThread);
		m_lpThread->m_Function(m_lpThread->m_Args);
		SetEvent(m_lpThread->m_ThreadCompleted.Get());

		delete this;

		return S_OK;
	}

private:
	Flow::CThread*	m_lpThread;
};

Bool ThreadHandler::Initialize()
{
	// RoInitialize
	//HRESULT hr = RoInitialize(RO_INIT_MULTITHREADED);
	//ASSERT(SUCCEEDED(hr));
	//if (FAILED(hr))
	//	return false;

	// Create Thread Pool
	HRESULT hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_System_Threading_ThreadPool).Get(), &s_lpThreadPool);
	ASSERT(SUCCEEDED(hr));
	if (FAILED(hr))
		return false;

	s_IsInitialized = true;

	return true;
}
void ThreadHandler::Uninitialize()
{
	ASSERT(s_IsInitialized);

	s_lpThreadPool->Release();
	//RoUninitialize();

	s_IsInitialized = false;
}
Bool ThreadHandler::IsInitialized()
{
	return s_IsInitialized;
}

IAsyncAction* ThreadHandler::RunASync(Flow::CThread* lpThread)
{
	lpThread->m_ThreadCompleted = Event(CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, WRITE_OWNER | EVENT_ALL_ACCESS));
	HRESULT hr = lpThread->m_ThreadCompleted.IsValid() ? S_OK : HRESULT_FROM_WIN32(GetLastError());
	ASSERT(SUCCEEDED(hr));
	if (FAILED(hr))
		return false;

	IAsyncAction* lpAction = nullptr;
	ThreadCallback* lpCallback = new ThreadCallback(lpThread);
	hr = s_lpThreadPool->RunAsync(Callback<IWorkItemHandler>(lpCallback, &ThreadCallback::Run).Get(), &lpAction);
	ASSERT(SUCCEEDED(hr));
	if (FAILED(hr))
		return nullptr;
	return lpAction;
}